<template>
  <div class="chart">
    <div ref="chart" id="newChart" :style="{ height: height, width: width }"></div>
  </div>
</template>
<script lang="ts">
import { markRaw, defineComponent, ref, onMounted, watch, onUnmounted, PropType } from 'vue'
import echarts from './renderer'
export default defineComponent({
  name: 'ChartView',
  props: {
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '350px'
    },
    autoResize: {
      type: Boolean,
      default: true
    },
    chartOption: {
      type: Object as PropType<any>,
      default: () => { }
    },
    type: {
      type: String,
      default: 'canvas'
    }
  },

  setup(props, { emit, expose }) {
    let chartVal = null;
    const chart = ref();

    const resizeHandler = () => {
      if (chartVal) {
        chartVal.resize()
      }
    }

    const getScale = (containRatio = true, baseWidth = 1920) => {
      const currentScale = document.documentElement.clientWidth / baseWidth
      const formattedScale = currentScale > 1 ? currentScale : 1
      const resultScale = containRatio ? formattedScale * window.devicePixelRatio : formattedScale
      return Math.ceil(resultScale)
    }

    const initChart = () => {
      chartVal = markRaw(echarts.init(chart.value, null, { devicePixelRatio: getScale() }))
      chartVal.setOption(props.chartOption)
      emit("chartValEmit", chartVal)
    }

    const setOptions = (option) => {
      clearChart()
      resizeHandler()
      if (chartVal) {
        chartVal.setOption(option)
      }
    }
    const clearChart = () => {
      chartVal && chartVal.clear()
    }

    onMounted(() => {
      initChart()
      if (props.autoResize) {
        window.addEventListener('resize', resizeHandler)
      }
    })

    onUnmounted(() => {
      chartVal.clear();
      chartVal.dispose();
      chartVal = null
      emit("chartValEmit", chartVal)
    });

    watch(
      () => props.chartOption,
      (newVal) => {
        setOptions(newVal)
      },
      { deep: true }
    )

    expose({
      setOptions,
    })

    return {
      chart
    }
  }
});

</script>